package org.bp.util;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.conn.util.InetAddressUtils;

/**
 * 网络相关辅助接口
 *
 */
public class NetUtils {
    private static Log log = LogFactory.getLog(NetUtils.class);
    
    /**
     * 枚举所有网卡
     */
    public static List<NetworkInterface> enumNetworkInterfaces() {
        try {
            List<NetworkInterface> netList = new ArrayList<NetworkInterface>();
            for (Enumeration<NetworkInterface> netEnum = NetworkInterface.getNetworkInterfaces();
                 netEnum.hasMoreElements(); ) {
                netList.add(netEnum.nextElement());
            }

            return netList;
        } catch (Exception e) {
            log.fatal(e.getMessage(), e);
            return null;
        }
    }


    /**
     * 获取本地网卡
     */
    public static NetworkInterface fetchLoopBackNetWorkInterface(){
        try {
            if (NetworkInterface.getNetworkInterfaces() == null) {
                return null;
            }
            for (Enumeration<NetworkInterface> netEnum = NetworkInterface.getNetworkInterfaces();
                 netEnum.hasMoreElements(); ) {
                NetworkInterface net = netEnum.nextElement();
                if(net.isLoopback()) {
                    return net;
                }
            }
        } catch (Exception e) {
            log.fatal(e);
            return null;
        }
        return null;
    }


    /**
     * 枚举所有物理网卡
     */
    public static List<NetworkInterface> enumPhysicalInterfaces() {
        try {
            List<NetworkInterface> netList = new ArrayList<NetworkInterface>();
            if (NetworkInterface.getNetworkInterfaces() == null) {
                return null;
            }
            for (Enumeration<NetworkInterface> netEnum = NetworkInterface.getNetworkInterfaces();
                 netEnum.hasMoreElements(); ) {
                NetworkInterface net = netEnum.nextElement();
                if(net.isPointToPoint() || net.isVirtual() || net.isLoopback() || !net.isUp()) {
                    continue;
                }

                netList.add(net);
            }

            return netList;
        } catch (Exception e) {
            log.fatal(e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取第一个物理网卡
     */
    public static NetworkInterface firstPhysicalInterface() {
        List<NetworkInterface> netList = enumPhysicalInterfaces();
        if(ObjectUtils.isNotNull(netList)) {
            return netList.get(0);
        } else {
            return null;
        }
    }

    /**
     * 判断一个端口号是否合法,主要判断是否超过了范围
     *
     * @param port 端口号数字
     * @return true表示合法,false表示非法
     */
    public static boolean isValidPort(int port) {
        return port >= 0 && port <= (int)Math.pow(2, 16) - 1;
    }

    /**
     * 解析ip:port格式的socket地址,并返回解析结果
     *
     * @param str ip:port格式的地址字符串
     * @return 解析结果
     */
    public static InetSocketAddress parseSocketAddress(String str) {
        assert str != null;
        String[] splits = str.split(":");
        if(splits.length != 2) {
            return null;
        }

        try {
            InetAddress addr = null;
            if (InetAddressUtils.isIPv4Address(splits[0]) || InetAddressUtils.isIPv6Address(splits[0])) {
                addr = InetAddress.getByName(splits[0]);
            } else {
                throw new InvalidParameterException();
            }

            int port = Integer.valueOf(splits[1]);
            if (!isValidPort(port)) {
                throw new RuntimeException();
            }

            return new InetSocketAddress(addr, port);
        } catch (Exception e) {
            return null;
        }
    }

    public static boolean isValidIP(String value) {
        return InetAddressUtils.isIPv4Address(value) && !InetAddressUtils.isIPv6Address(value);
    }
    
    /**
	 * 获取ip对应的MAC
	 * @param ip
	 * @return
	 */
    public static String getMACAddress(String ip) {  
        String str = "";  
        String macAddress = "";  
        InputStreamReader ir = null;
        LineNumberReader input = null;
        try {  
            Process p = Runtime.getRuntime().exec("nbtstat -A " + ip);  
            ir = new InputStreamReader(p.getInputStream());  
            input = new LineNumberReader(ir);  
            for (int i = 1; i < 100; i++) {  
                str = input.readLine();  
                if (str != null) {  
                    if (str.indexOf("MAC Address") > 1) {  
                        macAddress = str.substring(  
                                str.indexOf("MAC Address") + 14, str.length());  
                        break;  
                    }  
                }  
            }  
        } catch (IOException e) {  
            e.printStackTrace(System.out);  
        } finally {
			StreamUtils.close(ir,input);
		}  
        return macAddress;  
    } 

}
